package learn.spring.persistence.support;

import com.doubo.redis.serializer.ProtostuffRedisSerializer;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
public class MyRedisConfig {
    private String redisHost = "xwsredis.redis.rds.aliyuncs.com";
    private String redisPass = "mwQPE5nVgUVfBL1X";
    private int redisDefaultDb = 0;
    private int redisMaxRedirections = 6;
    private int redisTimeout = 15000;
    private boolean redisPoolTestOnBorrow = true;
    private int redisPoolMaxIdle = 30;
    private int redisPoolMaxWait = 6000;
    private int redisPoolMaxTotal = 100;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {

        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setDatabase(redisDefaultDb);
        configuration.setHostName(redisHost);
        configuration.setPassword(RedisPassword.of(redisPass));
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(redisPoolMaxIdle);
        poolConfig.setMaxTotal(redisPoolMaxTotal);
        poolConfig.setMaxWaitMillis(redisPoolMaxWait);
        poolConfig.setTestOnBorrow(redisPoolTestOnBorrow);
        JedisClientConfiguration jedisClientConfiguration = JedisClientConfiguration.builder().usePooling().poolConfig(poolConfig).and().connectTimeout(Duration.ofSeconds(redisTimeout))
                .readTimeout(Duration.ofSeconds(redisTimeout)).build();

        return new JedisConnectionFactory(configuration, jedisClientConfiguration);
    }

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        ProtostuffRedisSerializer protostuffRedisSerializer = new ProtostuffRedisSerializer();
        redisTemplate.setHashValueSerializer(protostuffRedisSerializer);
        redisTemplate.setValueSerializer(protostuffRedisSerializer);
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

}
